<?php

if (!defined('MOODLE_INTERNAL')) {
    die('Direct access to this script is forbidden.');
}

global $CFG;
require_once($CFG->dirroot . '/blocks/formal_langs/block_formal_langs.php');
require_once($CFG->dirroot . '/blocks/formal_langs/simpletest/common.php');
require_once($CFG->dirroot . '/blocks/formal_langs/langs_code/predefined/block_formal_langs_eng_simple_language.php');

class block_formal_langs_simple_eng_test extends UnitTestCase {

    private $langdbrecord;
    private $lang = null;
    private $strings = array();

    public function setUp() {
        $this->langdbrecord = new Object();
        $this->langdbrecord->id = 1;
        $this->langdbrecord->version = 1;
        $this->langdbrecord->parser_enabled = true;
        $this->lang = new block_formal_langs_eng_simple_language($this->langdbrecord);
    }

    public function test_lang_constructor() {
        $this->assertNotNull($this->lang);
        $this->assertTrue($this->lang->could_parse());
        $this->assertTrue($this->lang->is_predefined());
        $this->assertEqual($this->lang->name(), 'eng_simple');
    }

    public function test_tokenize_1() {
        $processedstring = new block_formal_langs_processed_string();
        $processedstring->string = '  the dog   bites   fly .   ';
        $stream = $this->lang->tokenize($processedstring);
        $result = $processedstring->tokenstream->tokens;
        
        $this->assertEqual(count($result), 5, 'There must be 5 lexemes in  \'the dog bites fly.\'');
        
        $this->assertEqual($result[0]->value(), 'the', 'Lexeme #1: the');
        $this->assertEqual($result[1]->value(), 'dog', 'Lexeme #2: dog');
        $this->assertEqual($result[2]->value(), 'bites', 'Lexeme #3: bites');
        $this->assertEqual($result[3]->value(), 'fly', 'Lexeme #4: fly');
        $this->assertEqual($result[4]->value(), '.', 'Lexeme #5: .');

        $this->assertIsA($result[0], 'block_formal_langs_token_article', 'There is an article token');
        $this->assertIsA($result[1], 'block_formal_langs_token_word', 'There is a word token');
        $this->assertIsA($result[2], 'block_formal_langs_token_word', 'There is a word token');
        $this->assertIsA($result[3], 'block_formal_langs_token_word', 'There is a word token');
        $this->assertIsA($result[4], 'block_formal_langs_token_punctuation', 'There is a punctuation token');

        // save processed string
        $this->strings['test_tokenize_1'] = $processedstring;
    }

    public function test_tokenize_2() {
        $processedstring = new block_formal_langs_processed_string();
        $processedstring->string = ' dog   bites fly';
        $stream = $this->lang->tokenize($processedstring);
        $result = $processedstring->tokenstream->tokens;
        
        $this->assertEqual(count($result), 3, 'There must be 3 lexemes in  \'the dog bites fly.\'');
        
        $this->assertEqual($result[0]->value(), 'dog', 'Lexeme #1: dog');
        $this->assertEqual($result[1]->value(), 'bites', 'Lexeme #2: bites');
        $this->assertEqual($result[2]->value(), 'fly', 'Lexeme #3: fly');
        $this->assertEqual($result[2]->description(), 'N', 'Lexeme #3 is noun');

        // save processed string
        $this->strings['test_tokenize_2'] = $processedstring;
    }

    public function test_parse() {
        $this->assertTrue(array_key_exists('test_tokenize_2', $this->strings), 'test_tokenize was successefull, we have correct tokenstream here');
        $processedstring = $this->strings['test_tokenize_2'];

        $result = $this->lang->parse($processedstring, false);

        $this->assertNotNull($result, 'There must be a AST, not null.');
    }
}
 ?>